package com.wcity.manage.common.utils.wx;


import com.wcity.manage.common.utils.StringUtil;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.*;
import java.util.Map.Entry;


/**
 * hb  2015年4月15日 
 * 微信支付工具类
 */
public class PayUtil {
	
	

	
	/**
	 * 获取客服端ip地址
	 * @param request
	 * @return
	 * hb 2015年4月20日
	 */
	public static String getIpAddr(HttpServletRequest request) {  
	    String ip = request.getHeader("x-forwarded-for");  
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("Proxy-Client-IP");  
	    }  
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getHeader("WL-Proxy-Client-IP");  
	    }  
	    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
	        ip = request.getRemoteAddr();  
	    }  
	    if(!StringUtil.isBlank(ip)){
	    	String[] tempIp = ip.split(",");
	    	return tempIp[0];
	    }
	    return ip.trim();  
	}  
	
	
	/**
	 * 对map key 进行排序并返回参数
	 * @param map
	 * @param
	 * @return
	 * hb 2015年4月20日
	 */
	public static String sort( Map<String ,String > map ){
		//字典排序
		 Collection<String> keyset= map.keySet();  
		 List<String> list = new ArrayList<String>(keyset);  
		//对key键值按字典升序排序  
	     Collections.sort(list);  
		 StringBuffer str = new StringBuffer();
	     for(int i=0;i<list.size();i++){
	     	if(i == list.size()-1){
				str.append(list.get(i));
				str.append("=");
				str.append(map.get(list.get(i)));
			}else {
				str.append(list.get(i));
				str.append("=");
				str.append(map.get(list.get(i)));
				str.append("&");
			}
	     }

	     return str.toString();
	}
	
	/**
	 * 解析微信发来的请求（XML）
	 * 
	 * @param  
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> parseXmlToMap(InputStream inputStream)
			throws Exception {
		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();
		System.out.println(inputStream);
		// 读取输入流
		SAXReader reader = new SAXReader();
		Document document = null;
		try{
			document = reader.read(inputStream);
		}catch(Exception e){
			e.printStackTrace();
		}
		
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		List<Element> elementList = root.elements();

		// 遍历所有子节点
		for (Element e : elementList)
			map.put(e.getName(), e.getText());
		// 释放资源
		inputStream.close();
		inputStream = null;
		return map;
	}
	
	
	/**
	 * 根据xml参数返回微信格式xml
	 * @param
	 * @return
	 * hb 2015年4月29日
	 */
	public static String returnXml(Map<String,String> paramMap){
		 StringBuffer str  = new StringBuffer();
		 str.append("<xml>");
		for(Entry<String, String> map :paramMap.entrySet()){
			str.append("<");
			str.append(map.getKey());
			str.append("><![CDATA[");
			str.append(map.getValue());
			str.append("]]></");
			str.append(map.getKey());
			str.append(">");
		}
		str.append("</xml>");
		return str.toString();
	}
	
	
	/**
	 * 将所有参数值按升序排序
	 * 
	 * @param params
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	public static String sortParamsToSign( Map<String, String> params ,String ENCODE) throws UnsupportedEncodingException {

		// 按参数名字典排序
		List<String> valList = Arrays.asList( params.keySet().toArray( new String[params.size()] ) );
		Collections.sort(valList);

		StringBuilder sb = new StringBuilder();

		for ( String k : valList ) {
			
			// 跳过 不被签名参数
			if ( k.equals( "sign" ) ) {
				continue;
			}
			sb.append(k).append( "=" ).append( URLEncoder.encode( params.get(k) , ENCODE ) ).append( "&" );
		}
		if ( params.size() > 1 )
			sb.delete( sb.length() - 1, sb.length() ); // 去掉最后一个字符
		return sb.toString();
	}

	
	/**
	 * MD5加密处理
	 * 
	 * @param src
	 * @return
	 */
	public final static String MD5LowerCase( String src ,String ENCODE) {
		
		StringBuffer buf = new StringBuffer("");
		
		try {
			// 获取MD5摘要算法对象
			MessageDigest digest = MessageDigest.getInstance( "MD5" );
			
			// 使用指定的字节更新摘要
			digest.update( src.getBytes( ENCODE ) );
			
			// 获取密文
			byte[] b = digest.digest();
			
			// 将密文转换成16进制的字符串形式
			int i = 0;
			
			for ( int offset = 0; offset < b.length; offset++ ) {
				
				i = b[offset];
				if ( i < 0 ) i += 256;
				if ( i < 16 ) buf.append( "0" );
				buf.append( Integer.toHexString(i) );
			}
			
		} catch ( Exception e ) {
			e.printStackTrace();
			return "";
		}
		return buf.toString();
	}

	/**
	 * Sha1加密
	 * @param str
	 * @return
     */
	public static String getSha1(String str){
		if(str==null||str.length()==0){
			return null;
		}
		char hexDigits[] = {'0','1','2','3','4','5','6','7','8','9',
				'a','b','c','d','e','f'};
		try {
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			mdTemp.update(str.getBytes("UTF-8"));

			byte[] md = mdTemp.digest();
			int j = md.length;
			char buf[] = new char[j*2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
				buf[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(buf);
		} catch (Exception e) {
			// TODO: handle exception
			return null;
		}
	}
    /**
     * map 转换成v1=value&v2=value2	
     * @param map
     * @return
     * hb 2015年5月7日
     */
	public static  String mapToParam(Map<String,String> map){
		StringBuffer str = new StringBuffer();
		for(Entry< String, String> param : map.entrySet()){
			str.append(param.getKey());
			str.append("=");
			str.append(param.getValue());
			str.append("&");
		}
		str.deleteCharAt(str.length()-1);
		return str.toString();
	}
	
	
	/**
	 * 解析微信发来的请求（XML）
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, String> parseXml(HttpServletRequest request)
			throws Exception {
		// 将解析结果存储在HashMap中
		Map<String, String> map = new HashMap<String, String>();

		// 从request中取得输入流
		InputStream inputStream = request.getInputStream();
		// 读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		// 得到xml根元素
		Element root = document.getRootElement();
		// 得到根元素的所有子节点
		List<Element> elementList = root.elements();

		// 遍历所有子节点
		for (Element e : elementList)
			map.put(e.getName(), e.getText());

		// 释放资源
		inputStream.close();
		inputStream = null;

		return map;
	}
	
	
}
